﻿#include "Keyboard.h"



namespace Base {
	// key event
	bool Keyboard::KeyIsPressed(unsigned char keycode)const {
		return m_keyStates[keycode];
	}
	std::optional<KeyboardEvent> Keyboard::ReadKey() {
		if (m_keyEventBuffer.size() > 0)
		{
			auto e = m_keyEventBuffer.front();
			m_keyEventBuffer.pop();
			return e;
		}
		return {};
	}
	bool Keyboard::KeyIsEmpty() const {
		return m_keyEventBuffer.empty();
	}
	void Keyboard::FlushKey() {
		m_keyEventBuffer = std::queue<KeyboardEvent>();
	}

	// char event
	std::optional<char> Keyboard::ReadChar() {
		if (m_charBuffer.size() > 0)
		{
			auto ch = m_charBuffer.front();
			m_charBuffer.pop();
			return ch;
		}
		return {};
	}
	bool Keyboard::CharIsEmpty() const {
		return m_charBuffer.empty();
	}
	void Keyboard::FlushChar() {
		m_charBuffer = std::queue<char>();
	}
	void Keyboard::Flush() {
		FlushKey();
		FlushChar();
	}

	// win32 callback
	void Keyboard::OnKeyPresed(unsigned char keycode) {
		m_keyStates[keycode] = true;
		m_keyEventBuffer.emplace(KeyboardEvent::Type::Press, keycode);
		TrimKeyBuffer();
	}
	void Keyboard::OnKeyReleased(unsigned char keycode) {
		m_keyStates[keycode] = false;
		m_keyEventBuffer.emplace(KeyboardEvent::Type::Release, keycode);
		TrimKeyBuffer();
	}
	void Keyboard::OnChar(char ch) {
		m_charBuffer.push(ch);
		TrimCharBuffer();
	}
	void Keyboard::ClearState() {
		m_keyStates.reset();
	}

	void Keyboard::TrimCharBuffer() {
		while (m_charBuffer.size() > kBufferSize)
		{
			m_charBuffer.pop();
		}
	}
	void Keyboard::TrimKeyBuffer() {
		while (m_keyEventBuffer.size() > kBufferSize)
		{
			m_keyEventBuffer.pop();
		}
	}
}